<!--AI推文-->

<script setup lang="ts">

import {type ChatGPTMessage, useGPTGernateDrawPropmt} from "~/composables/chathooks";
import AudioPlayer from "~/components/video/AudioPlayer.vue";
import {useUtilsUploadFileToOSS} from "~/utils/FileUtils";
import {Animations, Resolution, Transitions, TypeList, VideoEffects, VoiceModels} from '~/data/ai/workeditdata'
import {nanoid} from "nanoid";
import type {TTSChannel, TweetData} from "~/utils/jiangying";
import ImageUpload from "~/components/ai/ImageUpload.vue";

import ImagePreviewFull from "~/components/ai/ImagePreviewFull.vue";
import Prompt from "~/components/ai/PromptBase.vue";
import DropSelctBase from "~/components/ai/DropSelctBase.vue";
import LabelBase from "~/components/ai/LabelBase.vue";
import VideoPlayer from "~/components/video/VideoPlayer.vue";
import {type TTSOptions, useVoiceTTS} from "~/composables/VoiceHooks";

// const selected = ref()


const {
  contents,
  roles,
  scenes,
  ckpt_id,
  Resolution_id,
  useVideo,
  animations,
  effects,
  transitions,
  apisource,
  narrator_voice_id,
  voiceModels,
  ttsChannel
} = storeToRefs(useWorkEditStore())
// const data = ref<any>(workEditData)

onMounted(() => {
  // 初始化socket
  // socketInit()
})


// 表头
const tableHeader = ['镜头', '操作', '文案', "人物场景", "提示词", "预览", "配音", "生成视频", "转场/特效/动画"]
// 一键生成文案
const messages = ref<ChatGPTMessage[]>([])
watch(messages, (newVal) => {
  // console.log(newVal)
}, {
  deep: true
})
/**
 * 重新生成单个项目的提示词
 */
const handleGeneratePromptSingle = async (index: number) => {
  //     用GPT生成提示词
  console.log(contents.value[index].content, messages)
  if (!contents.value[index].content) {
    return
  }
  const _scene_desc = scenes.value.find(item => item.id === contents.value[index].scene_id)?.description || ""
  const _role_desc = roles.value.find(item => item.title === contents.value[index].role)?.description || ""
  console.log('任务和场景特征分别是', _scene_desc, _role_desc)
  const {content} = await useGPTGernateDrawPropmt(contents.value[index].content || "", messages, {
    scence: _scene_desc,
    features: _role_desc,
  })
  //   保存提示词
  contents.value[index].prompts = content
}
/**
 * 批量生成提示词
 */
const handleGeneratePrompt = async () => {
  for (let i = 0; i < contents.value.length; i++) {
    await handleGeneratePromptSingle(i)
  }
}

/**
 * 重新绘制单个图像
 */
const handleGenerateImageSingle = async (index: number) => {
  //   提交绘画任务
  await ComfyUI.Initalize()
  const _output = await ComfyUI.text2img({
    width: Resolution[Resolution_id.value].width,
    height: Resolution[Resolution_id.value].height,
    positive: contents.value[index].prompts || '',
    filename_prefix: `AItweet-${index}-${nanoid(10)}`,
    ckpt_name: ComfyUI.ckpt_names[ckpt_id.value],
    sd3_aspect_ratio: Resolution_id.value === 0 ? '9:16' : '16:9',   //根据选择的分辨率设定sd3的比例
  }, {
    apisource: apisource.value,
    workflow_name: 'text2img_tweet'
  })
  if (!_output || !_output.output || !_output.output[0]) {
    return
  }
  //如果有角色,则需要换脸
  if (contents.value[index].role && _output.status === 'success') {
    // 换脸
    console.log("开始换脸")
    const output = await ComfyUI.faceswap({
      image_path_origin: _output.output[0],
      image_path_face: roles.value[contents.value[index].role!].src,
    }, {
      workflow_name: 'faceSwap_tweet'
    })
    if (output && output.output && output.output[0]) {
      contents.value[index].images.unshift(output.output[0])
    }
  } else {
    contents.value[index].images.unshift(_output.output[0])
  }
  //index重置为0
  contents.value[index].choose_image_index = 0
}
/**
 * 批量绘图
 */
const handleGenerateImage = async () => {
  for (let i = 0; i < contents.value.length; i++) {
    //   提交绘画任务
    handleGenerateImageSingle(i)
  }
}


const {localVitsUrl, localChatttsUrl, useLocalVits, useLocalChatTTS} = storeToRefs(useWorkEditStore())
const ttsOptions = computed(() => {
  return {
    ttsChannel: ttsChannel.value,
    useChattts: ttsChannel.value === 'ChatTTS',
    useVits: ttsChannel.value === 'GPTVits',
    useLocalChattts: useLocalChatTTS.value,
    useLocalVits: useLocalVits.value,
  } as TTSOptions
})
/**
 * 重新生成单个配音
 */
const handleGenerateAudioSingle = async (index: number) => {
  //如果是对话则根据角色查找对应的声音模型
  let voice_model_id = narrator_voice_id.value
  if (contents.value[index].isTalk) {
    voice_model_id = roles.value[contents.value[index].role]?.voicemodel_id || 0
  }
  //   文本转语音)
  const voiceurl = await useVoiceTTS({
    text: contents.value[index].content!,
    ...voiceModels[voice_model_id]
  }, ttsOptions.value)
  if (voiceurl) {
    contents.value[index].audio.unshift(voiceurl)
  }
}
/**
 * 批量生成配音
 */
const handleGenerateAudio = async () => {
  for (let i = 0; i < contents.value.length; i++) {
    //   文本转语音
    await handleGenerateAudioSingle(i)
  }
}
/**
 * 生成单个视频
 */
const handleGenerateVideoSingle = (index: number) => {
  //图片生成视频
  const imageurl = contents.value[index].images[contents.value[index].choose_image_index || 0]
  if (!imageurl) {
    useSnackbarStore().showWarningMessage('请先生成图像')
    return
  }
  // //   上传到oss
  // const video_url = await useUtilsUploadFileToOSS(video)
  //   保存视频
  ComfyUI.image2video({
    image_path_origin: imageurl,
    video_frames: 25,
  }, {
    workflow_name: 'img2video_tweet'
  }).then(output=>{
    if(output?.status==='success' && output.output){
      contents.value[index].video = output.output[0]
    }
  })

}

/**
 * 批量生成视频
 */
const handleGenerateVideo = async () => {
  for (let i = 0; i < contents.value.length; i++) {
    handleGenerateVideoSingle(i)
  }
}


/**
 * 一键生成
 */
const handleAllDone = async () => {
  await handleGeneratePrompt()
  //生成图片和音频可以并行
  await Promise.all([handleGenerateImage(), handleGenerateAudio()])
  // await handleGenerateImage()
  // await handleGenerateAudio()
  await handleGenerateVideo()
}

/**
 * 添加分镜头
 */
const handleTweetAddMirror = (id: number) => {
  const newMirror = {
    content: "这是新添加的内容",
    prompts: "这是提示词",
    images: ["https://wangbo0808.oss-cn-shanghai.aliyuncs.com/aidraw/image/temps/155694.png"],
    choose_image_index: 0,
    audio: [],
    role: "",
    video: "",
    transition: '',
    video_effect: '',
    animation: ''
  } as TweetData
  contents.value.splice(id + 1, 0, newMirror)
}
/**
 * 删除分镜
 */
const handleTweetDeleteMirror = (id: number) => {
  contents.value.splice(id, 1)
}
/**
 * 保存项目
 */
const handleSaveProject = async () => {
  // 保存项目
  const res = await JiangYing.saveProject()
  if (res) {
    useSnackbarStore().showSuccessMessage('保存成功')
  }
}

/**
 * 导出剪映文件
 */
const handleExportClip = () => {
  JiangYing.getContent(contents.value)
}

// /**
//  * 上传测试
//  */
// const handleUploadTest = async () => {
//   useVocieVitsTextToSpeech({text: "你好啊，这是一个测试"})
//   const file = new File(["test"], "test.txt", {type: "text/plain"});
//   await useUtilsUploadFileToOSS(file)
// }
// const test = () => {
//   // JiangYing.getContent(data.value.contents)
// }


//图片预览相册
const preview_src = ref("")
const preview_visiable = ref(false)
/**
 * 全屏预览图片
 * @param index
 * @param i
 */
const handlePreviewFull = (index: number, i: number) => {
  console.log('点击轮播图')
  preview_src.value = contents.value[index].images[i]
  preview_visiable.value = true
}
/**
 * 删除当前预览图片
 */
const handleDeleteImage = (index: number) => {
  //将choose index减小1
  if (contents.value[index]) {
    console.log("删除元素", contents.value[index].choose_image_index)
    contents.value[index].images.splice(contents.value[index].choose_image_index, 1)
    contents.value[index].choose_image_index! > 0 ? contents.value[index].choose_image_index!-- : contents.value[index].choose_image_index = 0
  }

}

// 导出剪映配置文件


</script>

<template>
  <v-container>

    <v-card>
      <!--        顶部操作按键-->
      <v-sheet class="d-flex justify-space-between align-center">
        <v-sheet>
          <v-btn class="ma-1" size="small" variant="flat" color="primary" @click="handleAllDone">一键创作</v-btn>
          <v-btn class="ma-1" size="small" variant="outlined" @click="handleGeneratePrompt">
            批量生成批示词
          </v-btn>
          <v-btn class="ma-1" size="small" variant="outlined" @click="handleGenerateImage">批量绘图
          </v-btn>
          <v-btn class="ma-1" size="small" variant="outlined" @click="handleGenerateAudio">批量配音
          </v-btn>
          <v-btn class="ma-1" size="small" variant="outlined" @click="handleGenerateVideo">批量生成视频
          </v-btn>
          <v-btn class="ma-1" size="small" variant="flat" color="primary" @click="handleSaveProject">保存项目
          </v-btn>
          <v-btn class="ma-1" size="small" variant="outlined" @click="handleExportClip">导出剪映配置文件
          </v-btn>
        </v-sheet>

      </v-sheet>
      <perfect-scrollbar height="300px">

        <v-table fixed-header fixed-footer height="900">
          <thead>
          <tr>
            <th v-for="(item, index) in tableHeader" :key="index" class="text-left">{{ item }}</th>
          </tr>
          </thead>
          <tbody>
          <tr v-for="(item,index) in contents" :key="index">
            <!--镜头ID-->
            <td># {{ index }}</td>
            <td>
              <!--              操作-->
              <v-sheet class="d-flex flex-column justify-center align-center">
                <!--              删除当前镜头-->
                <v-btn class="my-1" size="small" color="warning" variant="elevated"
                       @click="handleTweetDeleteMirror(index)">删除分镜
                </v-btn>
                <!--              拆分分镜-->
                <!--                <v-btn class="my-1" size="small" color="primary" variant="elevated">拆分镜头</v-btn>-->
                <!--              添加分镜-->
                <v-btn class="my-1" size="small" color="primary" variant="elevated"
                       @click="handleTweetAddMirror(index)">添加镜头
                </v-btn>
              </v-sheet>

            </td>
            <!--            文案-->
            <td>
              <v-sheet width="300" class="d-flex justify-space-between align-center">
                <Prompt v-model="item.content" :rows="4"></Prompt>
                <!--                <v-btn size="small" variant="text" icon="mdi-translate-variant"></v-btn>-->
              </v-sheet>
            </td>
            <!--            人物形象-->
            <td>
              <v-sheet width="100" class="flex justify-content-center">
                <label-base>预设角色</label-base>
                <drop-selct-base :options="roles" v-model="item.role" optionLabel="title"
                                 optionValue="id"></drop-selct-base>
                <label-base>预设场景</label-base>
                <drop-selct-base :options="scenes" v-model="item.scene_id" optionLabel="title"
                                 optionValue="id"></drop-selct-base>
              </v-sheet>

            </td>
            <!--            提示词-->
            <td>
              <v-sheet style="font-size: 10px" width="300" class="d-flex justify-space-between align-center">
                <Prompt v-model="item.prompts" :rows="4"></Prompt>
                <!--                重新生成提示词按钮-->
                <V-tooltip location="top">
                  <v-label class="text-caption">重新生成提示词</v-label>
                  <template v-slot:activator="{ props }">
                    <v-btn size="small" v-bind="props" variant="text" icon="mdi-refresh"
                           @click="handleGeneratePromptSingle(index)"></v-btn>
                  </template>
                </V-tooltip>
              </v-sheet>
            </td>

            <!--            预览-->
            <td>
              <v-sheet class="d-flex align-center" width="200">
                <v-carousel v-model="item.choose_image_index" height="100" hide-delimiters progress>
                  <template v-slot:prev="{ props }">
                    <v-btn
                        icon="mdi-chevron-left"
                        size="small"
                        color="primary"
                        variant="text"
                        @click="props.onClick"
                    ></v-btn>
                  </template>
                  <template v-slot:next="{ props }">
                    <v-btn
                        icon="mdi-chevron-right"
                        size="small"
                        color="primary"
                        variant="text"
                        @click="props.onClick"
                    ></v-btn>
                  </template>
                  <v-carousel-item
                      v-for="(image,i) in item.images"
                      :key="i"
                      :src="image"
                      @click="handlePreviewFull(index,i)"
                  >
                  </v-carousel-item>

                </v-carousel>
                <!--                <a-image :src="item.images[item.choose_image_index]" alt="Image" width="100px" preview/>-->
                <v-sheet class="flex-column d-flex align-center">
                  <!--                  前一张图片-->
                  <!--                  <v-sheet v-show="item.images[item.choose_image_index-1]">-->
                  <!--                    <V-tooltip location="top">-->
                  <!--                      <v-label class="text-caption">前一张图片</v-label>-->
                  <!--                      <template v-slot:activator="{ props }">-->
                  <!--                        <v-btn size="small" v-bind="props" variant="text" icon="mdi-chevron-left"-->
                  <!--                               @click="handlePreviewPrev(index)"></v-btn>-->
                  <!--                      </template>-->
                  <!--                    </V-tooltip>-->
                  <!--                  </v-sheet>-->

                  <!--                重新生成图像按钮-->
                  <V-tooltip location="top">
                    <v-label class="text-caption">重新生图</v-label>
                    <template v-slot:activator="{ props }">
                      <v-btn size="small" v-bind="props" variant="text" icon="mdi-refresh"
                             @click="handleGenerateImageSingle(index)"></v-btn>
                    </template>
                  </V-tooltip>
                  <!--                  后一张图片-->
                  <!--                  <v-sheet v-show="item.images[item.choose_image_index+1]">-->
                  <!--                    <V-tooltip location="top">-->
                  <!--                      <v-label class="text-caption">后一张图片</v-label>-->
                  <!--                      <template v-slot:activator="{ props }">-->
                  <!--                        <v-btn size="small" v-bind="props" variant="text" icon="mdi-chevron-right"-->
                  <!--                               @click="handlePreviewNext(index)"></v-btn>-->
                  <!--                      </template>-->
                  <!--                    </V-tooltip>-->
                  <!--                  </v-sheet>-->
                  <!--                  删除当前index图片-->
                  <v-sheet v-show="item.images[item.choose_image_index||0]">
                    <V-tooltip location="top">
                      <v-label class="text-caption">删除当前图片</v-label>
                      <template v-slot:activator="{ props }">
                        <v-btn color="warning" size="x-small" v-bind="props" variant="text" icon="mdi-delete"
                               @click="handleDeleteImage(index)"></v-btn>
                      </template>
                    </V-tooltip>
                  </v-sheet>

                </v-sheet>
              </v-sheet>
            </td>
            <td>
              <!--            配音-->
              <v-sheet class="d-flex align-center flex-column">
                <!--              对话？旁白？-->
                <a-checkbox v-model:checked="item.isTalk">{{ item.isTalk ? '对话' : '旁白' }}</a-checkbox>
                <v-sheet v-show="item.audio[0]" class="d-flex align-center flex-column">
                  <audio-player :src="item.audio[0]||''"></audio-player>
                </v-sheet>
                <!--                重新生成配音-->
                <V-tooltip location="top">
                  <v-label class="text-caption">重新配音</v-label>
                  <template v-slot:activator="{ props }">
                    <v-btn size="small" v-bind="props" variant="text" icon="mdi-refresh"
                           @click="handleGenerateAudioSingle(index)"></v-btn>
                  </template>
                </V-tooltip>
              </v-sheet>
            </td>

            <td>
              <!--              生成视频-->
              <v-sheet class="d-flex align-center flex-row">
                <video-player v-show="item.video" :src="item.video" controls></video-player>
                <!--                生成单个视频-->
                <V-tooltip location="top">
                  <v-label class="text-caption">生成单个视频</v-label>
                  <template v-slot:activator="{ props }">
                    <v-btn size="small" v-bind="props" variant="text" icon="mdi-refresh"
                           @click="handleGenerateVideoSingle(index)"></v-btn>
                  </template>
                </V-tooltip>
              </v-sheet>

            </td>
            <td>
              <!--              转场 特效  动画-->
              <v-sheet width="100" class="flex justify-content-center">
                <!--                转场-->
                <drop-selct-base :options="transitions" v-model="item.transition" optionLabel="name"
                                 optionValue="resource_id"></drop-selct-base>
                <!--特效-->
                <drop-selct-base :options="effects" v-model="item.video_effect" optionLabel="name"
                                 optionValue="resource_id"></drop-selct-base>
                <!--动画-->
                <drop-selct-base :options="animations" v-model="item.animation" optionLabel="name"
                                 optionValue="resource_id"></drop-selct-base>

              </v-sheet>
            </td>
          </tr>
          </tbody>
          <!--          <template v-slot:bottom>-->
          <!--            <div class="text-center pt-2">-->
          <!--              <v-pagination length="3"></v-pagination>-->
          <!--            </div>-->
          <!--          </template>-->
        </v-table>
      </perfect-scrollbar>
    </v-card>
  </v-container>
  <image-preview-full v-model:visible="preview_visiable" v-model:src="preview_src" @close="preview_visiable=false"/>
</template>

<style scoped lang="scss">
.user-card {
  height: 1000px;
}

</style>
